<?php
//=======================================
//###################################
// Kayako Web Solutions
//
// Source Copyright 2001-2004 Kayako Infotech Ltd.
// Unauthorized reproduction is not allowed
// License Number: $%LICENSE%$
// $Author: mslaria $ ($Date: 2007/07/19 13:40:49 $)
// $RCSfile: functions_livesupport.php,v $ : $Revision: 1.33 $ 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//###################################
//=======================================

if (!defined("INSWIFT")) {
	trigger_error("Unable to process $PHP_SELF", E_USER_ERROR);
}

function insertVisitorFootprint($properties) {
	global $dbCore;
	/**
	* !!REMEMBER!! DECIDE ON HASNOTE, TOPULL, LISTBGCOLOR HERE!
	*/

	$result = $dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."visitorfootprints` (`sessionid`, `pageurl`, `pagehash`, `pagetitle`, `country`, `countrycode`, `dateline`, `lastactivity`, `ipaddress`, `hostname`, `referrer`, `resolution`, `colordepth`, `browsername`, `browserversion`, `browsercode`, `appversion`, `searchenginename`, `searchstring`, `searchengineurl`, `platform`, `operatingsys`, `rowbgcolor`, `rowfrcolor`, `hasnote`, `topull`, `campaignid`, `campaigntitle`) VALUES('". $dbCore->escape($properties["sessionid"]) ."', '". $dbCore->escape($properties["location"]) ."', '". $dbCore->escape(md5($properties["location"])) ."', '". $dbCore->escape($properties["pagetitle"]) ."', '". $dbCore->escape($properties["country"]) ."', '". $dbCore->escape($properties["countrycode"]) ."', '". $dbCore->escape(DATENOW) ."', '". $dbCore->escape(DATENOW) ."', '". $dbCore->escape($properties["ipaddress"]) ."', '". $dbCore->escape($properties["host"]) ."', '". $dbCore->escape($properties["referrer"]) ."', '". $dbCore->escape($properties["resolution"]) ."', '". $dbCore->escape($properties["colordepth"]) ."', '". $dbCore->escape($properties["browsername"]) ."', '". $dbCore->escape($properties["browserversion"]) ."', '". $dbCore->escape($properties["browsercode"]) ."', '". $dbCore->escape($properties["appversion"]) ."', '". $dbCore->escape($properties["searchenginename"]) ."', '". $dbCore->escape($properties["searchstring"]) ."', '". $dbCore->escape($properties["searchengineurl"]) ."', '". $dbCore->escape($properties["platform"]) ."', '". $dbCore->escape($properties["operatingsys"]) ."', '". $dbCore->escape($properties["rowbgcolor"]) ."', '". $dbCore->escape($properties["rowfrcolor"]) ."', '". intval($properties["hasnotes"]) ."', '". intval($properties["topull"]) ."', '". intval($properties["campaignid"]) ."', '". $dbCore->escape($properties["campaigntitle"]) ."');");

	return $result;
}

/**
* Updates the last activity and other stuff on an already existing footprint
*/
function updateVisitorFootprint($sessionid, $pageurl) {
	global $dbCore;
	if (!empty($sessionid) && !empty($pageurl)) {
		$pagehash = md5($pageurl);
		$result = $dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."visitorfootprints` SET `lastactivity` = '". $dbCore->escape(DATENOW) ."' WHERE `sessionid` = '". $dbCore->escape($sessionid) ."' AND `pagehash` = '". $dbCore->escape($pagehash) ."';");
		return $result;
	} else {
		return false;
	}
}

/**
* Flushes all visitors out which have had no activity since $timeline, always make sure that $timeline is atlaeast 5-10 seconds more than the update interval.
*/
function flushVisitors() {
	global $dbCore, $settings;

	$timeline = DATENOW - $settings->store["security_visitorinactivity"];
	
	$dbCore->query("SELECT `sessionid` FROM `". TABLE_PREFIX ."sessions` WHERE `sessiontype` IN('". SESSION_VISITOR ."', '". SESSION_CHAT ."') AND `lastactivity` <= '". $dbCore->escape($timeline) ."';", 2);
	while ($dbCore->nextRecord(2))
	{
		$delsession[] = $dbCore->Record2["sessionid"];
	}

	if (count($delsession) > 0)
	{
		$dbCore->query("DELETE FROM `". TABLE_PREFIX ."visitorfootprints` WHERE `sessionid` IN(". buildIN($delsession) .");");
		$dbCore->query("DELETE FROM `". TABLE_PREFIX ."sessions` WHERE `sessionid` IN(". buildIN($delsession) .");");
	}

	return true;
}

/**
* Checks to see if the given session id is active visitor sessionid
*/
function isActiveVisitorSession($sessionid)
{
	global $dbCore, $_SWIFT;

	$result = $dbCore->queryFetch("SELECT `sessionid`, `sessiontype` FROM `". TABLE_PREFIX ."sessions` WHERE `sessionid` = '". $dbCore->escape($sessionid) ."';");
	if ($result["sessionid"] = $sessionid && $result["sessiontype"] == SESSION_VISITOR)
	{
		return true;
	}

	return false;
}

/**
* Checks for search engine from given url, also returns query string
*/
function checkSearchEngine($fullurl) {
	$url = parse_url($fullurl);
	parse_str($url["query"], $query);
	$ret = array();
	if (stristr($url["host"], "google")) {
		$ret["name"] = "Google";
		$ret["url"] = "http://www.google.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;
	} else if (stristr($url["host"], "yahoo")) {
		$ret["name"] = "Yahoo!";
		$ret["url"] = "http://www.yahoo.com";
		$ret["query"] = $query["p"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "teoma")) {
		$ret["name"] = "Teoma";
		$ret["url"] = "http://www.teoma.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "overture")) {
		$ret["name"] = "Overture";
		$ret["url"] = "http://www.overture.com";
		$ret["query"] = $query["Keywords"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "msn")) {
		$ret["name"] = "MSN";
		$ret["url"] = "http://www.msn.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "netscape")) {
		$ret["name"] = "Netscape";
		$ret["url"] = "http://www.netscape.com";
		$ret["query"] = $query["netscape"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "northernlight")) {
		$ret["name"] = "Northernlight";
		$ret["url"] = "http://www.northernlight.com";
		$ret["query"] = $query["qr"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "looksmart")) {
		$ret["name"] = "LookSmart";
		$ret["url"] = "http://www.looksmart.com";
		$ret["query"] = $query["key"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "look")) {
		$ret["name"] = "look.com";
		$ret["url"] = "http://www.look.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "lycos")) {
		$ret["name"] = "Lycos";
		$ret["url"] = "http://www.lycos.com";
		$ret["query"] = $query["query"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "infoseek")) {
		$ret["name"] = "Infoseek";
		$ret["url"] = "http://www.infoseek.com";
		$ret["query"] = $query["qt"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "hotbot")) {
		$ret["name"] = "HotBot";
		$ret["url"] = "http://www.hotbot.com";
		$ret["query"] = $query["query"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "excite")) {
		$ret["name"] = "Excite";
		$ret["url"] = "http://www.excite.com";
		$ret["query"] = $query["search"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "dogpile")) {
		$ret["name"] = "DogPile";
		$ret["url"] = "http://www.dogpile.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "dmoz")) {
		$ret["name"] = "dmoz.org";
		$ret["url"] = "http://www.dmoz.org";
		$ret["query"] = $query["search"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "ask")) {
		$ret["name"] = "Ask";
		$ret["url"] = "http://www.ask.com";
		$ret["query"] = $query["ask"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "altavista")) {
		$ret["name"] = "Altavista";
		$ret["url"] = "http://www.altavista.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;		
	} else if (stristr($url["host"], "alltheweb")) {
		$ret["name"] = "Alltheweb";
		$ret["url"] = "http://www.alltheweb.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;
	} else if (stristr($url["host"], "search.com")) {
		$ret["name"] = "C|Net Search";
		$ret["url"] = "http://www.search.com";
		$ret["query"] = $query["q"];
		$ret["fullurl"] = $fullurl;
	} else {
		return false;
	}
	return $ret;
}

/**
* Retrieves the country data based on dotted ip address
*/
function getCountry($dottedip) {
	global $dbCore;
	$ipnumber = ip2number($dottedip);
	$dbCore->query("SELECT `country_name`, `country_code2`, `country_code3` FROM `". TABLE_PREFIX ."countryinfo` WHERE `ip_from` <= '". $dbCore->escape($ipnumber) ."' AND `ip_to` >= '". $dbCore->escape($ipnumber) ."';");
	$dbCore->nextRecord();
	$ret = array();
	$ret["countryname"] = trim($dbCore->Record["country_name"]);
	$ret["countrycode2"] = trim($dbCore->Record["country_code2"]);
	$ret["countrycode3"] = trim($dbCore->Record["country_code3"]);
	return $ret;
}

/*
* Prints an image depending upon size specified best way to communicate after JS has been loaded
*/
function echoImage($type)
{
	header("Content-Type: image/gif");
	$type++;

	switch ($type)
	{
		case "1":
			echo base64_decode("R0lGODlhAQAEAIAAAP/a2gAAACH5BAAAAAAALAAAAAABAAQAAAIChFEAOw==");
			break;
		case "2":
			echo base64_decode("R0lGODlhAgAEAIAAAKEGBgAAACH5BAAAAAAALAAAAAACAAQAAAIDhG8FADs=");
			break;
		case "3":
			echo base64_decode("R0lGODlhAwAEAIAAAI5wcAAAACH5BAAAAAAALAAAAAADAAQAAAIDhI9WADs=");
			break;
		case "4":
			echo base64_decode("R0lGODlhBAAEAIAAAH4/PwAAACH5BAAAAAAALAAAAAAEAAQAAAIEhI8JBQA7");
			break;
	}
}

/**
* Resets the visitor status
*/
function resetVisitorStatus($sessionid)
{
	global $dbCore;

	if (empty($sessionid))
	{
		return false;
	}

	$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."sessions` SET `status` = '0' WHERE `sessionid` = '". $dbCore->escape($sessionid) ."';");
}

/*
* Returns BOOL Value depending upon the status of staff visitor monitor (Online/Offline)
*/
function isStaffMonitorOnline($departmentid)
{
	global $dbCore, $_SWIFT;

	// Only support winapp for now, if we ever add a web based monitor we will need to change this.
	$staffidlist = $staffgroupidlist = $onlinestaffidlist = $awaystaffidlist = $backstaffidlist = array();

	$dbCore->query("SELECT staff.staffid, staff.groupassigns, staffgroup.staffgroupid, sessions.status FROM `". TABLE_PREFIX ."sessions` AS sessions LEFT JOIN `". TABLE_PREFIX ."staff` AS staff ON (sessions.typeid = staff.staffid) LEFT JOIN `". TABLE_PREFIX ."staffgroup` AS staffgroup ON (staff.staffgroupid = staffgroup.staffgroupid) WHERE sessions.sessiontype IN('". SESSION_WINAPP ."', '". SESSION_MONITOR ."') and sessions.lastactivity >= '". (DATENOW-180) ."';");
	while ($dbCore->nextRecord())
	{
		if ($dbCore->Record["status"] == STATUS_ONLINE)
		{
			$staffidlist[] = $dbCore->Record["staffid"];
			$onlinestaffidlist[] = $dbCore->Record["staffid"];
			if ($dbCore->Record["groupassigns"] == 1)
			{
				$staffgroupidlist[] = $dbCore->Record["staffgroupid"];
			}
		} else if ($dbCore->Record["status"] == STATUS_AWAY || $dbCore->Record["status"] == STATUS_AUTOAWAY) {
			$awaystaffidlist[] = $dbCore->Record["staffid"];
		} else if ($dbCore->Record["status"] == STATUS_BACK) {
			$backstaffidlist[] = $dbCore->Record["staffid"];
		}
	}

	// Is department id set to 0?
	if (empty($departmentid) && count($staffidlist) > 0)
	{
		return STATUS_ONLINE;
	} else if (empty($departmentid) && count($awaystaffidlist) > 0) {
		return STATUS_AWAY;
	} else if (empty($departmentid) && count($backstaffidlist) > 0) {
		return STATUS_BACK;
	} else if (!empty($departmentid)) {
		// Check to see if the staff we have are assigned to this department
		$dbCore->query("SELECT departments.departmentid FROM `". TABLE_PREFIX ."departments` AS departments LEFT JOIN `". TABLE_PREFIX ."staffassigns` AS staffassigns ON (staffassigns.departmentid = departments.departmentid) LEFT JOIN `". TABLE_PREFIX ."groupassigns` AS groupassigns ON (groupassigns.departmentid = departments.departmentid) WHERE staffassigns.staffid IN (". buildIN($staffidlist) .") OR groupassigns.staffgroupid IN(". buildIN($staffgroupidlist) .") GROUP BY departments.departmentid;");
		while ($dbCore->nextRecord())
		{
			// does this department match our department?
			if ($dbCore->Record["departmentid"] == $departmentid)
			{
				return STATUS_ONLINE;
			}
		}
	}

	return STATUS_OFFLINE;
}

/**
* Returns an array of online/offline departments
*/
function getDepartmentsStatus($departmentid)
{
	global $_SWIFT, $dbCore, $module;
	// First get the online departments
	$online = $onlineids = $staffidlist = $staffgroupidlist = array();

	// Get the id of staff members and their groups that are online first
	$dbCore->query("SELECT staff.staffid, staff.groupassigns, staffgroup.staffgroupid, sessions.status FROM `". TABLE_PREFIX ."sessions` AS sessions LEFT JOIN `". TABLE_PREFIX ."staff` AS staff ON (sessions.typeid = staff.staffid) LEFT JOIN `". TABLE_PREFIX ."staffgroup` AS staffgroup ON (staff.staffgroupid = staffgroup.staffgroupid) WHERE sessions.sessiontype IN ('". SESSION_WINAPP ."', '". SESSION_MONITOR ."');");
	while ($dbCore->nextRecord())
	{
		if ($dbCore->Record["status"] != STATUS_ONLINE)
		{
			continue;
		}

		$staffidlist[] = $dbCore->Record["staffid"];
		if ($dbCore->Record["groupassigns"] == "1")
		{
			$staffgroupidlist[] = $dbCore->Record["staffgroupid"];			
		}
	}

	// Now get all the departments that are assigned to either the given staffgroups or directly to staff member
	$cnt = 0;
	$departmentidlist = array();

	$dbCore->query("SELECT departments.departmentid, departments.title, departments.departmentmodule, departments.departmenttype FROM `". TABLE_PREFIX ."departments` AS departments LEFT JOIN `". TABLE_PREFIX ."tgroupassigns` AS tgroupassigns ON (tgroupassigns.toassignid = departments.departmentid AND tgroupassigns.type = '". TGROUP_DEPARTMENT ."') LEFT JOIN `". TABLE_PREFIX ."groupassigns` AS groupassigns ON (groupassigns.departmentid = departments.departmentid) LEFT JOIN `". TABLE_PREFIX ."staffassigns` AS staffassigns ON (staffassigns.departmentid = departments.departmentid) WHERE tgroupassigns.tgroupid = ". $_SWIFT["tgroup"]["tgroupid"] ." AND (staffassigns.staffid IN (". buildIN($staffidlist) .") OR groupassigns.staffgroupid IN(". buildIN($staffgroupidlist) ."));");

	while ($dbCore->nextRecord())
	{
		if (in_array($dbCore->Record["departmentid"], $departmentidlist) || $dbCore->Record["departmenttype"] != "public")
		{
			continue;
		}
		
		$departmentidlist[] = $dbCore->Record["departmentid"];
		// We only add those departments that have their type set to livesupport module
		if ($dbCore->Record["departmentmodule"] == MODULE_LIVESUPPORT && empty($departmentid))
		{
			$doadd = true;
		} else if ($dbCore->Record["departmentmodule"] == MODULE_LIVESUPPORT && $departmentid == $dbCore->Record["departmentid"]) {
			$doadd = true;
		} else {
			$doadd = false;
		}

		if ($doadd)
		{
			$onlineids[] = $dbCore->Record["departmentid"];
			$online[$cnt]["departmentid"] = $dbCore->Record["departmentid"];
			$online[$cnt]["title"] = $dbCore->Record["title"];
			$cnt++;
		}
	}

	$offline = $offlineids = array();
	$cnt = 0;
	// Now get all departments, see if its online already, if not set it to offline
	
	$dbCore->query("SELECT departments.departmentid, departments.title, departments.departmentmodule, departments.departmenttype FROM `". TABLE_PREFIX ."departments` AS departments LEFT JOIN `". TABLE_PREFIX ."tgroupassigns` AS tgroupassigns ON (tgroupassigns.toassignid = departments.departmentid AND tgroupassigns.type = '". TGROUP_DEPARTMENT ."') WHERE tgroupassigns.tgroupid = ". $_SWIFT["tgroup"]["tgroupid"] ." AND departments.departmentid NOT IN(". buildIN($onlineids) .") AND departments.departmentmodule = '". MODULE_LIVESUPPORT ."' ORDER BY departments.displayorder ASC;");

	//$dbCore->query("SELECT `departmentid`, `title`, `departmenttype` FROM `". TABLE_PREFIX ."departments` WHERE `departmentid` NOT IN(". buildIN($onlineids) .") AND departmentmodule = '". MODULE_LIVESUPPORT ."';");
	while ($dbCore->nextRecord())
	{
		if (in_array($dbCore->Record["departmentid"], $departmentidlist) || $dbCore->Record["departmenttype"] != "public")
		{
			continue;
		}
		
		$departmentidlist[] = $dbCore->Record["departmentid"];
		if (empty($departmentid))
		{
			$doadd = true;
		} else if ($departmentid == $dbCore->Record["departmentid"]) {
			$doadd = true;
		} else {
			$doadd = false;
		}

		if ($doadd)
		{
			$offlineids[] = $dbCore->Record["departmentid"];
			$offline[$cnt]["departmentid"] = $dbCore->Record["departmentid"];
			$offline[$cnt]["title"] = $dbCore->Record["title"];
			$cnt++;
		}
	}

	$result["online"] = $online;
	$result["offline"] = $offline;

	return $result;
}

/**
* Gets the staff with least amount of active chats at a given moment
*/
function getRoundRobinStaff($departmentid, $staffidignorelist = "")
{
	global $dbCore, $_SWIFT;

	if (!is_array($staffidignorelist))
	{
		$staffidignorelist = array();
	}

	$timefetch = DATENOW-60;
	$activestaffcount = $leaststaffcount = $returnstaffid = 0;
	$staffidlist = array();

	// We first get all the staff members assigned to this department
	$dbCore->query("SELECT staff.staffid, staff.groupassigns, groupassigns.groupassignid FROM `". TABLE_PREFIX ."staff` AS staff LEFT JOIN `". TABLE_PREFIX ."staffassigns` AS staffassigns ON (staffassigns.staffid = staff.staffid) LEFT JOIN `". TABLE_PREFIX ."groupassigns` AS groupassigns ON (groupassigns.staffgroupid = staff.staffgroupid) WHERE staffassigns.departmentid = '". $dbCore->escape($departmentid) ."' OR groupassigns.departmentid = IF(staff.groupassigns='1','". $dbCore->escape($departmentid) ."', '0');");
	while ($dbCore->nextRecord())
	{
		$staffidlist[] = $dbCore->Record["staffid"];
	}

	// Now get all the staff members that are online
	$_sessionlist = array();
	$dbCore->query("SELECT * FROM `". TABLE_PREFIX ."sessions` WHERE sessiontype IN ('". SESSION_WINAPP ."', '". SESSION_MONITOR ."') AND lastactivity >= '". $dbCore->escape($timefetch) ."' AND typeid IN (". buildIN($staffidlist) .");");
	while ($dbCore->nextRecord())
	{
		if (!in_array($dbCore->Record["typeid"], $staffidignorelist))
		{
			$_sessionlist[$dbCore->Record["sessionid"]] = $dbCore->Record;
		}
	}

	$_staffcountlist = $_onlinestaffidlist = $_newstaffcountlist = $_groupcount = array();
/*	$fp = fopen("./cache/testchat.txt", "a+");
	fwrite($fp, "[".date("d M Y h:i:s A")."]: Starting Round Robin\n");
	fclose($fp);*/

	$_allstafffree = true;

	foreach ($_sessionlist as $key=>$val)
	{
		if ($val["status"] != STATUS_ONLINE)
		{
			continue;
		}
		// Now we get the count of requests for each staff
		$staffid = $val["typeid"];
		if (!in_array($staffid, $_onlinestaffidlist))
		{
			$_onlinestaffidlist[] = $staffid;
			$_newstaffcountlist[$staffid] = 1;
		}
		$_timethreshold = DATENOW-(60*5); // 5 Minutes for last post
		$staffcount = $dbCore->queryFetch("SELECT COUNT(*) AS totalcount FROM `". TABLE_PREFIX ."chatobjects` WHERE `chatstatus` = '". CHAT_INCHAT ."' AND `staffid` = '". $dbCore->escape($staffid) ."';");
		if (empty($staffcount["totalcount"]))
		{
			$staffcount["totalcount"] = 0;
		} else {
			$_allstafffree = false;
		}
/*		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: ". $staffid .":". intval($staffcount["totalcount"]) ."\n");
		fclose($fp);*/

		$_staffcountlist[$staffid] = intval($staffcount["totalcount"]);

		// We put the different staff users under different groups
		$_groupcount[$staffcount["totalcount"]][] = $staffid;
	}

	asort($_staffcountlist);
	$_keymap = array_keys($_staffcountlist);
//	print_r($_staffcountlist);
//	print_r($_keymap);

	// We have no valid data to return
	if (!isset($_staffcountlist[$_keymap[0]]))
	{
/*		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: No Valid Staff Users Available\n");
		fclose($fp);*/
		return false;

	// Do we have other staff members in same group?
	} else if (isset($_staffcountlist[$_keymap[0]]) && count($_groupcount[$_staffcountlist[$_keymap[0]]]) > 1) {
/*		ob_start();
		print_r($_groupcount);
		$_contents = ob_get_contents();
		ob_end_clean();
		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: We have others in same group!: ". $_contents ."\n");
		fclose($fp);*/

		// We will now need to shuffle them up and return some staff
		$_grouplist = $_groupcount[$_staffcountlist[$_keymap[0]]];
		shuffle($_grouplist);
/*		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: Shuffle Result: ". $_grouplist[0]."\n");
		fclose($fp);*/

		return $_grouplist[0];

	// Only one staff member in this group?
	} else if (isset($_staffcountlist[$_keymap[0]]) && count($_groupcount[$_staffcountlist[$_keymap[0]]]) == 1) {
/*		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: We have only one staff in the group! returning the same!: ". $_keymap[0]."\n");
		fclose($fp);*/
		return $_keymap[0];
	} else if (_is_array($_onlinestaffidlist) && $_allstafffree) {
		$_newtimethreshold = DATENOW-(60*60); // 60 Minutes for last post
/*		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: We have other staff online and everyones free!\n");
		fclose($fp);*/

		// We get 10 chats that have had some update in last one hour
		$dbCore->query("SELECT `staffid` FROM `". TABLE_PREFIX ."chatobjects` WHERE (`chatstatus` = '". CHAT_ENDED ."' OR `chatstatus` = '". CHAT_INCHAT ."') AND `staffid` IN (". buildIN($_onlinestaffidlist) .") AND `dateline` > '". intval($_newtimethreshold) ."' ORDER BY `chatobjectid` DESC LIMIT 10;");
		while ($dbCore->nextRecord())
		{
			$_newstaffcountlist[$dbCore->Record["staffid"]]++;
		}

/*		ob_start();
		print_r($_newstaffcountlist);
		$_contents = ob_get_contents();
		ob_end_clean();
		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: New Staff Count List: ". $_contents ."\n");
		fclose($fp);*/


		asort($_newstaffcountlist);
		$_newkeymap = array_keys($_newstaffcountlist);
		if ($_newkeymap[0])
		{
/*			$fp = fopen("./cache/testchat.txt", "a+");
			fwrite($fp, "[".date("d M Y h:i:s A")."]: Found ONE!: ". $_newkeymap[0] ."\n");
			fclose($fp);*/
			return $_newkeymap[0];
		}

		return $_keymap[0];
	} else {
/*		$fp = fopen("./cache/testchat.txt", "a+");
		fwrite($fp, "[".date("d M Y h:i:s A")."]: If all else fails return default value: ". $_keymap[0] ."!\n");
		fclose($fp);*/

		return $_keymap[0];
	}


	return $_keymap[0];
/*
	foreach

		if ($staffcount["totalcount"] <= $leaststaffcount && !in_array($staffid, $staffidignorelist))
		{
			$leaststaffcount = $staffcount["totalcount"];
			$returnstaffid = $staffid;
		} else {
			$returnstaffidnores = $staffid;
		}
		$activestaffcount++;
	}

	if ($returnstaffid == "")
	{
		return $returnstaffidnores;
	}

	return $returnstaffid;*/
}

/**
* Gets the total number of pending chat queues, if $ignore is specified then those specific visitor session ids are ignored
*/
function getTotalPendingChatQueue($ignore)
{
	global $dbCore, $_SWIFT;

	$timefetch = DATENOW-60;

	$total = $dbCore->queryFetch("SELECT COUNT(*) as totalitems FROM `". TABLE_PREFIX ."sessions` AS sessions LEFT JOIN `". TABLE_PREFIX ."chatobjects` AS chatobjects ON (sessions.typeid = chatobjects.chatobjectid) WHERE chatobjects.chatstatus = '". CHAT_INCOMING ."' AND chatobjects.visitorsessionid NOT IN(". buildIN($ignore) .") AND sessions.sessiontype = '". SESSION_CHAT ."' AND sessions.lastactivity >= '". $timefetch ."';");
	return $total["totalitems"];
}

/**
* Generates a random name for visitor
*/
function generateRandomVisitorName()
{
	global $_SWIFT, $dbCore;

	return $_SWIFT["language"]["visitorpullname"];
}

/**
* Blocks the visitor for all the eternity, must be some pesky user..
*/
function blockVisitor($sessionid, $staffid)
{
	global $dbCore;

	$visitor = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."sessions` WHERE `sessionid` = '". $dbCore->escape($sessionid) ."';");
	if (is_array($visitor))
	{
		$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."visitorbans` (`ipaddress`, `dateline`, `staffid`) VALUES('". $dbCore->escape($visitor["ipaddress"]) ."', '". DATENOW ."', '". $dbCore->escape($staffid) ."');");
			
		// Delete the data too
		$dbCore->shutdownQuery("DELETE FROM `". TABLE_PREFIX ."sessions` WHERE `sessionid` = '". $dbCore->escape($sessionid) ."';");
		$dbCore->shutdownQuery("DELETE FROM `". TABLE_PREFIX ."visitorfootprints` WHERE `sessionid` = '". $dbCore->escape($sessionid) ."';");

		return true;
	}

	return false;
}

/**
* Adds the message submitted to the chat queue
*/
function submitChatMessage($chatsessionid, $msgtype, $message, $dobase = false)
{
	global $dbCore, $_SWIFT;

	$_chatobject = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."sessions` AS sessions LEFT JOIN `". TABLE_PREFIX ."chatobjects` AS chatobjects ON (sessions.typeid = chatobjects.chatobjectid) WHERE sessions.sessionid = '". $dbCore->escape($chatsessionid) ."';");

	if ($_chatobject["chatobjectid"] != "")
	{
		$msgarray = array("type" => ACTION_MSG, "contents" => $message, "base64" => $dobase);

		if ($msgtype == MESSAGE_CLIENT)
		{
			$fullname = $_chatobject["userfullname"];
		} else if ($msgtype == MESSAGE_STAFF) {
			$fullname = $_SWIFT["staff"]["fullname"];
		}
		

		$dbCore->query("SELECT * FROM `". TABLE_PREFIX ."chatchilds` WHERE `chatobjectid` = '". $dbCore->escape($_chatobject["chatobjectid"]) ."';");
		while ($dbCore->nextRecord())
		{
			if ($msgtype == MESSAGE_STAFF && $dbCore->Record["staffid"] == $_SWIFT["staff"]["staffid"])
			{
				// Seems like this is the same chat child for the staff that is submitting the msg, dont do anything because the msg display for staff will be carried out by javascript
			} else {
				// For every child id we need to insert a message into message queue
				$appendquery .= "('". intval($_chatobject["chatobjectid"]) ."', '". $dbCore->escape($dbCore->Record["chatchildid"]) ."', '". intval($_SWIFT["staff"]["staffid"]) ."', '". DATENOW ."', '". $dbCore->escape($fullname) ."', '". $dbCore->escape(serialize($msgarray)) ."', '". ACTION_MSG ."'),";
			}
		}

		if ($msgtype == MESSAGE_STAFF && $_chatobject["chattype"] != CHAT_STAFF)
		{
			// Is the message type staff? If yes, we need to insert one message for client too, default chatchildid for client is 0
			$appendquery .= "('". intval($_chatobject["chatobjectid"]) ."', '". "0" ."', '0', '". DATENOW ."', '". $fullname ."', '". $dbCore->escape(serialize($msgarray)) ."', '". ACTION_MSG ."'),";
		}

		// Messages for staff inserted
		if (!empty($appendquery))
		{
			$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."messagequeue` (`chatobjectid`, `chatchildid`, `staffid`, `dateline`, `name`, `contents`, `msgtype`) VALUES ". preg_replace("/,$/", "", $appendquery) .";");
		}

		// Get the data for this from chatdata now
		$_chatdata = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."chatdata` WHERE `chatobjectid` = '". $dbCore->escape($_chatobject["chatobjectid"]) ."';");

		$_chatdataproc = unserialize($_chatdata["contents"]);
		$convocount = count($_chatdataproc);
		$_chatdataproc[$convocount]["type"] = iif($msgtype == MESSAGE_STAFF, "staff", "client");
		$_chatdataproc[$convocount]["name"] = $fullname;
		$_chatdataproc[$convocount]["message"] = $message;
		$_chatdataproc[$convocount]["base64"] = $dobase;

		$_chatdataupd = serialize($_chatdataproc);

		$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."chatdata` SET `contents` = '". $dbCore->escape($_chatdataupd) ."' WHERE `chatobjectid` = '". $_chatobject["chatobjectid"] ."';");

		if ($msgtype == MESSAGE_STAFF)
		{
			$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."chatobjects` SET `lastpostactivity` = '". DATENOW ."', `staffpostactivity` = '". DATENOW ."' WHERE `chatobjectid` = '". intval($_chatobject["chatobjectid"]) ."';");
		} else {
			$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."chatobjects` SET `lastpostactivity` = '". DATENOW ."', `userpostactivity` = '". DATENOW ."' WHERE `chatobjectid` = '". intval($_chatobject["chatobjectid"]) ."';");
		}

		return true;
	} else {

		return false;
	}
}

/**
* Submits a chat action
*/
function submitChatAction($chatobjectid, $submittype, $actiontype, $data)
{
	global $dbCore, $_SWIFT;

	$_chatobject = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."chatobjects` WHERE `chatobjectid` = '". $dbCore->escape($chatobjectid) ."';");

	if ($_chatobject["chatobjectid"] != "")
	{
		$msgarray = array("type" => $actiontype, "contents" => $data);

		$fullname = $_SWIFT["staff"]["fullname"];

		$dbCore->query("SELECT * FROM `". TABLE_PREFIX ."chatchilds` WHERE `chatobjectid` = '". $dbCore->escape($_chatobject["chatobjectid"]) ."';");
		while ($dbCore->nextRecord())
		{
			if ($dbCore->Record["staffid"] == $_SWIFT["staff"]["staffid"] && ($actiontype == ACTION_URL || $actiontype == ACTION_TYPING))
			{
				// Dont do anything if its the same staff who pushed this action and the action is supposed to open a URL
			} else if ($dbCore->Record["staffid"] == $_SWIFT["staff"]["staffid"] && $actiontype == ACTION_CHATLEAVE) {
				// Same here
			} else if ($_chatobject["chattype"] == CHAT_STAFF && $dbCore->Record["staffid"] == $_SWIFT["staff"]["staffid"] && $_chatobject["userid"] == $_SWIFT["staff"]["staffid"]) {
				// Reserved
			} else {
				$appendquery .= "('". intval($_chatobject["chatobjectid"]) ."', '". $dbCore->escape($dbCore->Record["chatchildid"]) ."', '". intval($_SWIFT["staff"]["staffid"]) ."', '". DATENOW ."', '". $dbCore->escape($fullname) ."', '". $dbCore->escape(serialize($msgarray)) ."', '". $dbCore->escape($actiontype) ."'),";
			}
		}

		// Only do a client submit if its either a client chat or if the submitter is staff and not client
		if ($_chatobject["chattype"] != CHAT_STAFF && $submittype == SUBMIT_STAFF)
		{
			$appendquery .= "('". intval($_chatobject["chatobjectid"]) ."', '". "0" ."', '0', '". DATENOW ."', '". $fullname ."', '". $dbCore->escape(serialize($msgarray)) ."', '". $dbCore->escape($actiontype) ."'),";
		}

		if (!empty($appendquery))
		{
			$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."messagequeue` (`chatobjectid`, `chatchildid`, `staffid`, `dateline`, `name`, `contents`, `msgtype`) VALUES ". preg_replace("/,$/", "", $appendquery) .";");
		}

		return true;
	} else {
		return false;
	}
}

/**
* Submits a chat child action
*/
function submitChatChildAction($chatobjectid, $chatchildid, $actiontype, $data)
{
	global $dbCore, $_SWIFT;

	$msgarray = array("type" => $actiontype, "contents" => $data);

	$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."messagequeue` (`chatobjectid`, `chatchildid`, `staffid`, `dateline`, `name`, `contents`, `msgtype`) VALUES ('". intval($chatobjectid) ."', '". $dbCore->escape($chatchildid) ."', '". intval($_SWIFT["staff"]["staffid"]) ."', '". DATENOW ."', '". $dbCore->escape($_SWIFT["staff"]["fullname"]) ."', '". $dbCore->escape(serialize($msgarray)) ."', '". $dbCore->escape($actiontype) ."');");

	return true;
}

/**
* Checks for banned status for this specific visitor
*/
function checkBannedStatus($overridecookie = false)
{
	global $cookie, $dbCore, $_SWIFT;

	$cookie->parseCookie("visitor");
	$bancookie = $cookie->getKey("visitor", "isbanned");

	if ($bancookie == "" || $overridecookie == true)
	{
		// it seems like we never did check this visitor to see if hes banned check now
		$banresult = $dbCore->queryFetch("SELECT `visitorbanid` FROM `". TABLE_PREFIX ."visitorbans` WHERE `ipaddress` = '". $dbCore->escape($_SWIFT["IP"]) ."' LIMIT 1;");
		if (trim($banresult["visitorbanid"]) != "")
		{
			// He is banned!
			$cookie->addCookie("visitor", "isbanned", "1");
			$isbanned = true;
		} else {
			$cookie->addCookie("visitor", "isbanned", "0");
			$isbanned = false;
		}
		$cookie->buildCookie("visitor");
	} else if ($bancookie == "1") {
		$isbanned = true;
	} else {
		$isbanned = false;
	}

	return $isbanned;
}

/**
* This function is used to add a visitor note
*/
function addVisitorNote($ipaddress, $note)
{
	global $dbCore, $_SWIFT;

	$dbCore->query("INSERT INTO `". TABLE_PREFIX ."visitornotes` (ipaddress, dateline, staffid, staffname) VALUES ('". $dbCore->escape($ipaddress) ."', '". DATENOW ."', '". $dbCore->escape($_SWIFT["staff"]["staffid"]) ."', '". $dbCore->escape($_SWIFT["staff"]["fullname"]) ."');");
	$visitornoteid = $dbCore->lastInsertId();
	$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."visitornotedata` (visitornoteid, contents) VALUES('". $dbCore->escape($visitornoteid) ."', '". $dbCore->escape($note) ."');");

	return true;
}

/**
* Highlights a given code with line numbers
*/
function highlightCode($rawcode){
	$rawcode = preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $rawcode);
	$split = split(SWIFT_CRLF, $rawcode);
	$linecount = count($split);  
  
	$data .= "<table bgcolor=\"#F7F7EF\" cellspacing=\"0\" width=\"100%\">";  
	$codehighlight = highlight_string($rawcode, true);
	$data .= "<tr><td bgcolor=#CCCFF7 width='1' align='right'><code>";
	for ($ii=0; $ii<$linecount; $ii++)
	{
		$data .= $ii+1;
		$data .= "<BR />";
	}
	$data .= "</code></td>"; 

	$data .= "<td style=\"padding-left: 5px\" align=\"left\" valign=\"top\">".SWIFT_CRLF;
	$data .= $codehighlight.SWIFT_CRLF;
	$data .= "</td></tr></table>".SWIFT_CRLF;  

	return $data;
}

/**
* Converts HTML to Javascript write statements
*/
function HTML2JS($html, $prefix, $dosplit = false, $isfunction = true)
{
	$html = preg_replace("#(\r\n|\r|\n)#s", SWIFT_CRLF, $html);
	if ($isfunction)
	{
		$prefix = $prefix ."(";
		$suffix = ")";
	}

	if ($dosplit)
	{
		$split = split(SWIFT_CRLF, $html);
		for ($ii=0; $ii<count($split); $ii++)
		{
			$jsdata .= $prefix.'"'.addslashes($split[$ii]).'"'. $suffix .';'.SWIFT_CRLF;
		}
	} else {
		$html = str_replace(SWIFT_CRLF, "", $html);
		$jsdata .= $prefix.'"'.addslashes($html).'"'. $suffix .';'.SWIFT_CRLF;
	}

	return $jsdata;
}

/**
* Ends a given chat
*/
function endChat($chatobjectid)
{
	global $_SWIFT, $dbCore;

	$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."chatobjects` SET chatstatus = '". CHAT_ENDED ."' WHERE chatobjectid = '". $dbCore->escape($chatobjectid) ."';");

	// Delete all chat childs
	$dbCore->shutdownQuery("DELETE FROM `". TABLE_PREFIX ."chatchilds` WHERE `chatobjectid` = '". $dbCore->escape($chatobjectid) ."';");

	return true;
}

/**
* Ends a given staff chat
*/
function endStaffChat($chatobjectid)
{
	global $dbCore, $_SWIFT;
	$conference = $noleave = false;

	$_chatobject = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."chatobjects` WHERE `chatobjectid` = '". $dbCore->escape($chatobjectid) ."';");
	if (empty($_chatobject["chatobjectid"]) || $_chatobject["chatstatus"] != CHAT_INCHAT)
	{
		return;
	}

	$childcount = 0;
	// Get the chat childs

	$dbCore->query("SELECT * FROM `". TABLE_PREFIX ."chatchilds` WHERE `chatobjectid` = '". $dbCore->escape($_chatobject["chatobjectid"]) ."';");
	while ($dbCore->nextRecord())
	{
		if ($dbCore->Record["staffid"] != "0" && $dbCore->Record["staffid"] != $_SWIFT["staff"]["staffid"])
		{
			// We have another staff in conference
			$staffid = $dbCore->Record["staffid"];
			$staffname = $_SWIFT["staffcache"][$staffid]["fullname"];
		} else if ($dbCore->Record["staffid"] == $_SWIFT["staff"]["staffid"]) {
			$chatchildid = $dbCore->Record["chatchildid"];
		}
		$childcount++;
	}

	// Is this a conference chat? if yes, we dont end it when leaving
	if (($childcount > 1 && $_chatobject["chattype"] == CHAT_CLIENT) || ($childcount > 2 && $_chatobject["chattype"] == CHAT_STAFF))
	{
		$conference = true;
	}			

	if ($conference)
	{
		$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."chatobjects` SET `staffid` = '". $dbCore->escape($staffid) ."', `staffname` = '". $dbCore->escape($staffname) ."' WHERE chatobjectid = '". $dbCore->escape($_chatobject["chatobjectid"]) ."';");
	} else {
		// Nuke the chat
		endChat($_chatobject["chatobjectid"]);
	}

	if ($conference)
	{
		if ($_SWIFT["settings"]["ls_depname"] == 1 && !empty($_SWIFT["departmentcache"][$_chatobject["departmentid"]]["title"]))
		{
			$_chatname = $_SWIFT["departmentcache"][$_chatobject["departmentid"]]["title"];
		} else {
			$_chatname = $_SWIFT["staff"]["fullname"];
		}

		submitChatAction($_chatobject["chatobjectid"], SUBMIT_STAFF, ACTION_CHATLEAVE, $_chatname);
	}
		
	if (isset($chatchildid) && $conference)
	{
		// Delete the child because the chat wasnt nuked
		$dbCore->shutdownQuery("DELETE FROM `". TABLE_PREFIX ."chatchilds` WHERE `chatchildid` = '". $dbCore->escape($chatchildid) ."';");
	}
}

/**
* Returns a chat object from given chat session id
*/
function getChatObjectFromSession($chatsessionid)
{
	global $dbCore, $_SWIFT;

	return $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."sessions` AS sessions LEFT JOIN `". TABLE_PREFIX ."chatobjects` AS chatobjects ON (sessions.typeid = chatobjects.chatobjectid) WHERE sessions.sessionid = '". $dbCore->escape($chatsessionid) ."';");
}

/**
* Gets a visitor session id
*/
function getVisitorSession($visitorsessionid)
{
	global $dbCore, $_SWIFT;

	$_visitorsession = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."sessions` WHERE `sessionid` = '". $dbCore->escape($visitorsessionid) ."';");
	
	if ($_visitorsession["sessiontype"] == SESSION_VISITOR)
	{
		return $_visitorsession;
	} else {
		return false;
	}
}

/**
* Returns total number of chat childs
*/
function getChatChildCount($chatobjectid)
{
	global $dbCore;

	return $dbCore->queryFetch("SELECT COUNT(*) AS totalitems FROM `". TABLE_PREFIX ."chatchilds` WHERE `chatobjectid` = '". $dbCore->escape($chatobjectid) ."';");
}

/**
* Updates the chat status of given chat object
*/
function updateChatStatus($chatobjectid, $chatstatus, $staffid = "", $staffname = "")
{
	global $dbCore;

	if (trim($staffid) != "" && trim($staffname) != "")
	{
		$extendedquery = ", staffid = '". $dbCore->escape($staffid) ."', staffname = '". $dbCore->escape($staffname) ."'";
	}

	$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."chatobjects` SET `chatstatus` = '". $chatstatus ."'". $extendedquery ." WHERE `chatobjectid` = '". 	$dbCore->escape($chatobjectid) ."';");

	return true;
}

/**
* Updates Session Status to given status, usefull for proactive chats
*/
function updateSessionStatus($sessionid, $status)
{
	global $dbCore;

	$dbCore->shutdownQuery("UPDATE `". TABLE_PREFIX ."sessions` SET `status` = '". $status ."' WHERE `sessionid` = '". $dbCore->escape($sessionid) ."';");

	return true;
}

/**
* Adds a Visitor Pull entry, for proactive chats
*/
function doVisitorPull($visitorsessionid)
{
	global $dbCore, $_SWIFT;

	$dbCore->shutdownQuery("INSERT INTO `". TABLE_PREFIX ."visitorpulls` (`visitorsessionid`, `staffid`, `dateline`) VALUES ('". $dbCore->escape($visitorsessionid) ."', '". $dbCore->escape($_SWIFT["staff"]["staffid"]) ."', '". DATENOW ."');");

	return true;
}

/**
* Flushes all Visitor Pull entries for given visitor session id
*/
function flushVisitorPulls($visitorsessionid)
{
	global $dbCore;

	$dbCore->shutdownQuery("DELETE FROM `". TABLE_PREFIX ."visitorpulls` WHERE `visitorsessionid` = '". $dbCore->escape($visitorsessionid) ."';");

	return true;
}

/**
* Gets all assigned departments to current staff
*/
function getAssignedLRDepartments()
{
	global $_SWIFT;

	$departmentlist = array();

	if ($_SWIFT["staff"]["groupassigns"] == 1)
	{
		foreach ($_SWIFT["groupassigncache"][$_SWIFT["staff"]["staffgroupid"]] as $key=>$val)
		{
			if (!in_array($val, $departmentlist))
			{
				$departmentlist[] = $val;
			}
		}		
	} else {
		foreach ($_SWIFT["staffassigncache"][$_SWIFT["staff"]["staffid"]] as $key=>$val)
		{
			if (!in_array($val, $departmentlist))
			{
				$departmentlist[] = $val;
			}
		}		
	}

	return $departmentlist;
}

/**
* Gets message count for given assigned departments of staff
*/
function getMessageCount()
{
	global $_SWIFT;

	$departmentlist = getAssignedLRDepartments();
	$messagecount = "0";

	// iterate through the departments
	foreach ($departmentlist as $key=>$val)
	{
		if (!empty($_SWIFT["livesupportcache"]["messagecount"][$val]))
		{
			$messagecount += $_SWIFT["livesupportcache"]["messagecount"][$val];
		}
	}

	return $messagecount;
}

function unescapeJSUnicode($strIn) {
	$strOut = '';
	$iPos = 0;
	$len = strlen ($strIn);

	while ($iPos < $len) {
		$charAt = substr ($strIn, $iPos, 1);

		if ($charAt == '%') {
			$iPos++;
			$charAt = substr ($strIn, $iPos, 1);

			if ($charAt == 'u') {
				// Unicode character
				$iPos++;
				$unicodeHexVal = substr ($strIn, $iPos, 4);
				$unicode = hexdec ($unicodeHexVal);
				$strOut .= '&#'.$unicode.';';
				$iPos += 4;
			} else {
				// Escaped ascii character
				$hexVal = substr ($strIn, $iPos, 2);

				if (hexdec($hexVal) > 127) {
					// Convert to Unicode 
					$strOut .= '&#'.hexdec ($hexVal).';';
				} else {
					$strOut .= chr (hexdec ($hexVal));
				}

				$iPos += 2;
			}
		} else {
			$strOut .= $charAt;
			$iPos++;
		}
	}

	return $strOut;
}
?>